


import win32com
from win32com.client import Dispatch, constants, GetObject



objSapGui = None
objSapApplication = None
bInit = False

tblConns = {}
iNextID = 1



# 初始化 [获取依赖对象]
def Init():
    global objSapGui
    global objSapApplication
    global bInit
    if bInit == False:
        objSapGui = GetObject("SAPGUI")
        objSapApplication = objSapGui.GetScriptingEngine
        bInit = True
    else:
        return True



# 卸载
def Unit():
    global tblConns
    for k, v in tblConns.items():
        if v["index"] > 0:
            CloseConnect(v["index"])
    tblConns = {}



# 连接到SAP服务器
def CreateConnect(sName):
    global bInit
    global objSapApplication
    global tblConns
    global iNextID
    if bInit:
        objConnect = objSapApplication.OpenConnection(sName)
        objSession = objConnect.Children(0)
        tblConn = {}
        tblConn["index"] = iNextID
        tblConn["connect"] = objConnect
        tblConn["session"] = objSession
        # 写入数据到全局列表中
        tblConns["obj" + str(iNextID)] = tblConn
        iNextID = iNextID + 1
        return iNextID - 1
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取连接
def GetConnect(sid):
    global bInit
    global objSapApplication
    global tblConns
    global iNextID
    if bInit:
        objConnect = objSapApplication.Children(sid)
        objSession = objConnect.Children(0)
        tblConn = {}
        tblConn["index"] = iNextID
        tblConn["connect"] = objConnect
        tblConn["session"] = objSession
        # 写入数据到全局列表中
        tblConns["obj" + str(iNextID)] = tblConn
        iNextID = iNextID + 1
        return iNextID - 1
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 关闭连接
def CloseConnect(iConnIdx):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["index"] = 0
        objConn["connect"].CloseConnection()
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 发送命令
def SendCMD(iConnIdx, sCMD):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].sendCommand(sCMD)
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 判断元素是否存在
def Exists(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        if objConn["session"].findById(sPath, False) == None:
            return False
        else:
            return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 修改元素文本
def SetText(iConnIdx, sPath, sText):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).text = sText
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取元素文本
def GetText(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).text
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 点击元素
def Click(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).press()
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 选择元素
def Select(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).select()
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 修改元素选择状态
def SetCheck(iConnIdx, sPath, bCheck):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).selected = bCheck
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取元素选择状态
def GetCheck(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).selected
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 发送按键
def SendKey(iConnIdx, sPath, iKey):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).sendVKey(iKey)
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 设置焦点
def SetFocus(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).setFocus()
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 设置光标位置
def SetCaretPos(iConnIdx, sPath, iPos):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).caretPosition = iPos
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 关闭窗口
def CloseWindow(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        objConn["session"].findById(sPath).close()
        return True
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取表格的列数
def GridView_ColCount(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).ColumnCount
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取表格的行数
def GridView_RowCount(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).RowCount
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取表格已显示的行数（SAP没有显示的行不可以操作，会报错）
def GridView_VisibleRowCount(iConnIdx, sPath):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).VisibleRowCount
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")



# 获取表格的单元格内容
def GridView_GetCellText(iConnIdx, sPath, iCol, iRow):
    global bInit
    global tblConns
    if bInit:
        objConn = tblConns.get("obj" + str(iConnIdx))
        if objConn == None:
            raise Exception("不存在的连接对象：" + str(iConnIdx))
        return objConn["session"].findById(sPath).GetCellValue(iRow, iCol)
    else:
        raise Exception("在使用 Connect 前请先调用 Init 函数初始化，并确保初始化成功")





# Test Script
if __name__ == '__main__':
    print(Init())
